package br.edu.ufcg.fpc;

import br.edu.ufcg.fpc.util.Util;

/**
 * Classe utilizada para criar e executar as threads.
 */
public class MutualExclusion {

	static int nThreads;
	
	public void execute(int nThreads, Class<? extends CriticalRegion> calculator, Boolean opt)
			throws InstantiationException, IllegalAccessException, InterruptedException {
		MutualExclusion.nThreads = nThreads;
		CriticalRegion[] threads = new CriticalRegion[nThreads];
		
		BakeryLockCR.CURRENT_MAX_ID = 0; //FIXME pegar id da thread
		
		// cria e executa as threads de acordo com o tipo de trava escolhido
		for (int i=0; i < nThreads; i++) {
			try {
				threads[i] = calculator.getConstructor(Boolean.class).newInstance(opt);
			} catch (NoSuchMethodException e) {
				threads[i] = calculator.newInstance();
			} catch (Exception e) {
				System.err.println("Something wrong happened");
				System.exit(1);
			}
			threads[i].start();
		}
		
		System.out.println("Time average to get into critical region:");
		for (int i=0; i < nThreads; i++) {
			threads[i].join();
			double mean = Util.calculateMean(threads[i].getTimes());
			double sd = Util.calculateStandardDeviation(threads[i].getTimes(), mean);
			System.out.printf(" - Thread %d: mean=%1.2f, sd=%1.2f\n", i, mean, sd);
		}
	}
	
}
